use std::time::{Duration, Instant};

use eframe::egui;
use egui::containers::scroll_area::ScrollArea;
use egui::widget_text::RichText;
use egui::widgets::text_edit::TextEdit;
use egui::widgets::Button;
use egui::Color32;
use egui::FontId;
use egui::Sense;
use egui::{FontData, FontDefinitions, FontFamily, Visuals};

use chrono::DateTime;
use chrono::Local;

use crate::file_tool;
use crate::work::Work;

#[derive(Default)]
pub struct MyApp {
    current_works_done: Vec<Work>,
    current_works_undo: Vec<Work>,
    is_show_dialog: bool,
    is_new_work: bool,
    //works_done_num: i8,
    work: Option<Work>, //暂存当前要处理的工作
    //双击检测字段
    button_clicked: bool,
    last_click_time: Option<Instant>,
    pub double_click_threshold: Duration,
    double_click_detected: bool,
    //
    current_date: DateTime<Local>,
}

impl MyApp {
    pub fn new(cc: &eframe::CreationContext<'_>) -> Self {
        let mut fonts = FontDefinitions::default();
        // Install my own font (maybe supporting non-latin characters):
        fonts.font_data.insert(
            "my_font".to_owned(),
            FontData::from_static(include_bytes!(
                "/home/owen/code/rust_project/egui-demo/STFangsong.ttf"
            )),
        ); // .ttf and .otf supported

        // Put my font first (highest priority):
        fonts
            .families
            .get_mut(&FontFamily::Proportional)
            .unwrap()
            .insert(0, "my_font".to_owned());

        // Put my font as last fallback for monospace:
        fonts
            .families
            .get_mut(&FontFamily::Monospace)
            .unwrap()
            .push("my_font".to_owned());
        cc.egui_ctx.set_fonts(fonts);
        // Set the theme as Light
        cc.egui_ctx.set_visuals(Visuals::light());
        //set font size
        let mut style = (*cc.egui_ctx.style()).clone();
        style.text_styles = [
            (
                egui::TextStyle::Body,
                egui::FontId::new(20.0, egui::FontFamily::Proportional),
            ),
            (
                egui::TextStyle::Button,
                egui::FontId::new(24.0, egui::FontFamily::Proportional),
            ),
            (
                egui::TextStyle::Heading,
                egui::FontId::new(24.0, egui::FontFamily::Proportional),
            ),
            // 其他文本样式也可以在这里设置
        ]
        .into();
        cc.egui_ctx.set_style(style);

        let mut my_app = Self::default();
        my_app.double_click_threshold = Duration::from_millis(300);
        my_app.current_date = Local::now();
        my_app
    }

    //读取并设置current_works_undo， current_works_done 值

    pub fn read_today_works(&mut self, file_name: String) {
        let op = file_tool::read_works_file(file_name.as_str());
        println!("read_today_works json {:?}", op);
        let mut works_all: Vec<Work> = vec![];
        //json to data
        match op {
            Some(json) => {
                let vec_works = serde_json::from_str(&json);
                match vec_works {
                    Ok(works) => works_all = works,
                    Err(e) => {
                        self.current_works_undo =
                            vec![Work::new(0, format!("{:?}", e), String::from(""))]
                    }
                }
            }
            None => {
                self.current_works_undo = vec![Work::new(
                    0,
                    String::from("读取文件失败2"),
                    String::from(""),
                )];
            }
        }

        //把工作按照状态分成两组
        if !works_all.is_empty() {
            for work in works_all {
                println!("work status {}", &work.status);
                if work.status == 1 || work.status == -1 {
                    self.current_works_done.push(work);
                } else {
                    self.current_works_undo.push(work);
                }
            }
        }

        println!("the works num: {}", self.current_works_undo.len());
    }
}

impl MyApp {
    // is_new_work: true 创建新work, false 打开存在的work
    fn work_detail_popwin(&mut self, ctx: &egui::Context) {
        println!("work_detail_detail...");
        let window_title = match &self.is_new_work {
            true => "添加工作",
            false => "查看工作",
        };

        if self.is_show_dialog {
            egui::Window::new(window_title)
                .default_pos([200.0, 150.0])
                .min_size(egui::vec2(500.0, 300.0)) // 设置固定的宽度和高度, 如果内容不够实际大小会比这个设置的要小。
                .show(ctx, |ui| {
                    ui.add(
                        TextEdit::singleline(&mut self.work.as_mut().unwrap().title)
                            .desired_width(800.0)
                            .hint_text("请输入工作标题..."),
                    );
                    ui.label("工作具体内容：");
                    ui.add(
                        TextEdit::multiline(&mut self.work.as_mut().unwrap().detail)
                            .min_size(egui::vec2(800.0, 200.0))
                            .hint_text("请输入详细信息...")
                            .desired_rows(5)
                            .lock_focus(true)
                            .interactive(true),
                    );
                    ui.horizontal(|ui| {
                        if self.is_new_work {
                            if ui.button("保存").clicked() {
                                println!("新增工作内容： {}", &self.work.clone().unwrap().detail);
                                self.is_show_dialog = false;
                                self.save_works();
                            }
                        } else {
                            if ui.button("保存").clicked() {
                                //   println!("新增工作内容： {}", &self.work.unwrap().detail);
                                self.is_show_dialog = false;
                                self.save_works();
                            }
                            if ui.button("完成").clicked() {
                                //  println!("新增工作内容： {}", self.work.unwrap().detail);
                                let mut work = self.work.clone().unwrap();
                                work.status = 1;
                                self.work = Some(work);
                                self.is_show_dialog = false;
                                self.save_works();
                            }
                            if ui.button("删除").clicked() {
                                //  println!("新增工作内容： {}", self.work.unwrap().detail);
                                let mut work = self.work.clone().unwrap();
                                work.status = -1;
                                self.work = Some(work);
                                self.is_show_dialog = false;
                                self.save_works();
                            }
                        }
                        if ui.button("关闭").clicked() {
                            // println!("新增工作内容： {}", &self.work.unwrap().detail);
                            self.is_show_dialog = false;
                        }
                    })
                });
        }
    }

    fn save_works(&mut self) {
        if self.work.is_none() {
            eprintln!("请填写今天的工作！");
            return ();
        }
        //这里应该判断这个工作的是已经存在的还是新增的 todo
        let mut works = vec![];
        if self.is_new_work {
            let _ = &self
                .current_works_undo
                .insert(0, self.work.clone().unwrap());
            works.extend(&self.current_works_undo);
            works.extend(&self.current_works_done);
        } else {
            match &self.work {
                Some(work) => {
                    println!(
                        ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>the detail to save status {:?}",
                        &self.work.clone().unwrap().status
                    );
                    if work.status == 0 {
                        let done_work_id = self.work.clone().unwrap().id;
                        let works_undo: Vec<Work> = self
                            .current_works_undo
                            .clone()
                            .into_iter()
                            .filter(|x| x.id != done_work_id)
                            .collect();
                        self.current_works_undo = works_undo;
                        let works_done: Vec<Work> = self
                            .current_works_done
                            .clone()
                            .into_iter()
                            .filter(|x| x.id != done_work_id)
                            .collect();
                        self.current_works_done = works_done;
                        let _ = &self
                            .current_works_undo
                            .insert(0, self.work.clone().unwrap());
                    } else {
                        println!("save to done vec");
                        let done_work_id = self.work.clone().unwrap().id;
                        let works_undo: Vec<Work> = self
                            .current_works_undo
                            .clone()
                            .into_iter()
                            .filter(|x| x.id != done_work_id)
                            .collect();
                        self.current_works_undo = works_undo;
                        let works_done: Vec<Work> = self
                            .current_works_done
                            .clone()
                            .into_iter()
                            .filter(|x| x.id != done_work_id)
                            .collect();
                        self.current_works_done = works_done;
                        let _ = &self
                            .current_works_done
                            .insert(0, self.work.clone().unwrap());
                    }
                }
                None => {}
            }

            works.extend(&self.current_works_undo);
            works.extend(&self.current_works_done);
        }
        let json = serde_json::to_string(&works).expect("Failed to serialize to JSON");
        let today_work_file_name = Local::now().format("%y-%m-%d").to_string();
        let _ = file_tool::write_works_file(json, today_work_file_name);
    }

    fn draw_main_content(
        &mut self,
        ctx: &egui::Context,
        ui: &mut egui::Ui,
        x: f32,
        y: f32,
        width: f32,
        height: f32,
        title: &str,
        rect_type: i8, //0 未完成  1 完成
    ) {
        //allocate_space 添加一块不能交互的区域
        //ui.allocate_space(egui::vec2(width, 50.0));

        let title_rect = egui::Rect::from_min_size(egui::pos2(x, y), egui::vec2(width, 50.0));
        //get the painter
        let painter = ui.painter();
        painter.rect_filled(title_rect, 0.0, egui::Color32::LIGHT_BLUE);
        painter.text(
            title_rect.center(),
            egui::Align2::CENTER_CENTER,
            title,
            egui::FontId::monospace(18.0),
            egui::Color32::BLACK,
        );

        //设置滚动区域
        let parent_rect = ui.max_rect();
        let parent_height = parent_rect.height();
        let scroll_area_rect = egui::Rect::from_min_size(
            egui::pos2(x, y + 50.0),
            egui::vec2(width, parent_height - y - 50.0 - 50.0),
        );

        // 分配空间给 ScrollArea
        ui.allocate_ui_at_rect(scroll_area_rect, |ui| {
            ScrollArea::vertical().id_salt(rect_type).show(ui, |ui| {
                let works = match rect_type {
                    0 => &self.current_works_undo,
                    _ => &self.current_works_done,
                };
                for item in works {
                    let color = match item.status {
                        0 => Color32::WHITE,
                        1 => Color32::LIGHT_GREEN,
                        -1 => Color32::DARK_RED,
                        2 => Color32::YELLOW,
                        _ => Color32::LIGHT_GREEN,
                    };
                    //let mut click_time = 0;
                    let response = ui.add(
                        Button::new(item.title.clone())
                            .min_size(egui::vec2(width, 25.0))
                            .fill(color)
                            .sense(Sense::click()),
                    );
                    response.clone().on_hover_text("双击可修改");
                    if response.clicked() {
                        if self.button_clicked
                            && !self.last_click_time.is_none()
                            && self.last_click_time.unwrap().elapsed() < self.double_click_threshold
                        {
                            println!("双击了！！！！！！！");
                            self.double_click_detected = true;
                            self.button_clicked = false; // 重置点击状态
                                                         //打开work 详情
                                                         //设置 self.work
                            self.work = Some(item.clone());
                            self.is_new_work = false; //设置弹框里是否为新work, false 编辑存在的工作
                            self.is_show_dialog = true;
                        } else {
                            self.button_clicked = true;
                            self.last_click_time = Some(Instant::now());
                        }
                    }
                    if self.double_click_detected {
                        println!("重置双击。。。");
                        self.double_click_detected = false; // 重置双击检测标志
                    }
                }
            });
        });
    }
}

impl eframe::App for MyApp {
    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
        /*
        egui::TopBottomPanel::top("top").show(ctx, |ui| {
            ui.horizontal(|ui| {
                if ui.button(" 昨  天 ").clicked() {
                    println!("yesterday");
                }
                if ui.button(" 明  天 ").clicked() {
                    println!("tomorow");
                }
                ui.label("版本: 0.1.0");
                ui.hyperlink_to("作者： 程序虫", "https://gitee.com/SnailCoder");
            })
        });
        */
        egui::CentralPanel::default().show(ctx, |ui| {

            ui.horizontal(|ui| {
                if ui.button("添加新Work...").clicked() {
                    self.is_show_dialog = true;
                    self.is_new_work = true;
                    let id = (&self.current_works_done.len() + &self.current_works_undo.len() + 1) as i8;
					println!("新 work Id 是  {}",id);
                    let  work_new_today = Work::new(id, "".to_string(), "".to_string());
                    self.work = Some(work_new_today);
                }

                ui.label(
                    RichText::new(format!(
                        "已完成{}项任务，待完成{}项任务。白色：未完成，黄色： 超时，绿色：已完成， 深红色： 删除",
                        &self.current_works_done.len(),
                        &self.current_works_undo.len()
                    ))
                    .font(FontId::proportional(15.0)),
                );
            });

            let parent_rect = ui.max_rect();
            let parent_width = parent_rect.width();
            let finished_work_position_x = parent_width * 0.7;
            let work_positon_x = 20.0;
            let start_y = 50.0;

            //show the old works
            let old_work_width = parent_width - finished_work_position_x;
            let work_width = parent_width - old_work_width - work_positon_x;
            //绘画待完成工作区域
            self.draw_main_content(
                ctx,
                ui,
                work_positon_x,
                start_y,
                work_width - 10.0,
                0.0,
                "待完成工作",
                0,
            );
            //绘画已经完成个工作区域

            self.draw_main_content(
                ctx,
                ui,
                finished_work_position_x,
                start_y,
                old_work_width,
                0.0,
                "已完成工作",
                1,
            );

            //因为egui 是及时模式，就是时刻在刷新，所以我们写的独立的方法调用只能通过全局参数控制
            //然后必须在update 里面直接调用。
            self.work_detail_popwin(ctx);

        }



        );

        //底部面板，用于显示底部按钮
        egui::TopBottomPanel::bottom("my_panel").show(ctx, |ui| {
            ui.horizontal(|ui| {
                if ui.button(" 昨  天 ").clicked() {
                    println!("yesterday");
                    self.current_works_done.clear();
                    self.current_works_undo.clear();
                    self.current_date = self.current_date - chrono::Duration::days(1);
                    let mut works_date = self.current_date.format("%y-%m-%d").to_string();
                    works_date.push_str(".json");
                    println!("yesterday {:?}", &self.current_date);
                    self.read_today_works(works_date);
                }
                if ui.button(" 明  天 ").clicked() {
                    println!("tomorow");
                    self.current_works_done.clear();
                    self.current_works_undo.clear();
                    self.current_date = self.current_date + chrono::Duration::days(1);
                    let mut works_date = self.current_date.format("%y-%m-%d").to_string();
                    works_date.push_str(".json");
                    println!("tomorow {:?}", &self.current_date);
                    self.read_today_works(works_date);
                }
                ui.label("版本: 0.1.0");
                ui.hyperlink_to("作者： 程序虫", "https://gitee.com/SnailCoder");
            })
        });
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_save_work() {
        let work = Work::new(5, String::from("test work"), String::from("detail test"));

        println!("the json string:   {}   ", work.to_json());
    }
}
